package com.jrx.anytxn.transaction.controller.api;

import com.jrx.anytxn.common.constant.Constants;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.exception.TxnRuntimeException;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.common.uitl.StringUtils;
import com.jrx.anytxn.customer.constant.CustomerConstant;
import com.jrx.anytxn.customer.dto.customer.CustomerRes;
import com.jrx.anytxn.customer.service.ICustomerService;
import com.jrx.anytxn.i18n.response.TxnRespResult;
import com.jrx.anytxn.param.entity.PrProductTable;
import com.jrx.anytxn.param.enums.BizTypeEnum;
import com.jrx.anytxn.param.service.product.IProductTableService;
import com.jrx.anytxn.redisson.service.RedissonLockService;
import com.jrx.anytxn.redisson.util.LockType;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.constant.TransErrMsgConstant;
import com.jrx.anytxn.transaction.dto.common.CommonAddReq;
import com.jrx.anytxn.transaction.dto.common.CommonReq;
import com.jrx.anytxn.transaction.dto.common.CommonRes;
import com.jrx.anytxn.transaction.dto.loan.*;
import com.jrx.anytxn.transaction.entity.AmLoanMainInfo;
import com.jrx.anytxn.transaction.entity.TlDisbursementLog;
import com.jrx.anytxn.transaction.entity.TlPaymentLog;
import com.jrx.anytxn.transaction.handler.ILoanHandler;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmLoanMainInfoMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlDisbursementLogMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlPaymentLogMapper;
import com.jrx.anytxn.transaction.service.IRepaymentPlanService;
import com.jrx.anytxn.transaction.service.ISmsService;
import com.jrx.anytxn.transaction.service.impl.DealGatewayServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Api(tags = "贷款相关接口")
@RestController
@RequestMapping(value = "/api/transaction/loan")
public class LoanController {

    private static final Logger logger = LoggerFactory.getLogger(LoanController.class);
    private static final BigDecimal BIG_DECIMAL_99 = new BigDecimal("99");

    @Autowired
    private ILoanHandler loanHandler;
    @Autowired
    private RedissonLockService redissonLockService;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private ISmsService smsService;
    @Resource
    private ExtAmLoanMainInfoMapper extAmLoanMainInfoMapper;
    @Autowired
    private IProductTableService productTableService;
    @Autowired
    private IRepaymentPlanService iRepaymentPlanService;
    @Autowired
    private ISmsService iSmsService;
    @Autowired
    private ExtTlPaymentLogMapper extTlPaymentLogMapper;
    @Autowired
    private DealGatewayServiceImpl dealGatewayService;
    @Autowired
    private ExtTlDisbursementLogMapper extTlDisbursementLogMapper;

    @ApiOperation(value = "贷款确认", notes = "贷款确认API")
    @PostMapping(value = "/loanConfirm")
    public TxnRespResult<LoanConfirmRes> loanConfirm(@Valid @RequestBody LoanConfirmReq loanConfirmReq)
            throws Exception {

        logger.debug("1.查询客户信息，判断客户信息是否存在,用户号：{}", loanConfirmReq.getUserId());
        CustomerRes customer = customerService.getCustomerByChannelAndUserId(loanConfirmReq.getChannel(),
                loanConfirmReq.getUserId(), loanConfirmReq.getTenantId());
        String lockKey = String.format(CustomerConstant.LOAN_REDIS_LOCK, loanConfirmReq.getTenantId(),
                customer.getFirstLevel().getCustomerId());
        logger.info("RedissionLock key:{}", lockKey);
        RLock lock = redissonLockService.getRLock(lockKey, LockType.REENTRANT_LOCK);
        try {
            boolean lockFlag = lock.tryLock(CustomerConstant.LOAN_REDIS_LOCK_WAITE_TIME,
                    CustomerConstant.LOAN_REDIS_LOCK_LESS_TIME, TimeUnit.SECONDS);
            logger.info("获取RedissionLock key:{},lockFlag:{}", lockKey, lockFlag);
            if (!lockFlag) {
                logger.error(TxnRespCode.TRANSACTION_PROCESSING.getMsg());
                throw new TxnBizException(TxnRespCode.TRANSACTION_PROCESSING.getCode(),
                        TxnRespCode.TRANSACTION_PROCESSING.getMsg());
            }
            TxnRespResult<LoanConfirmRes> result = new TxnRespResult<>();
            logger.debug("贷款确认开始startTime:{}", result.getStartTime());
            LoanConfirmRes res = loanHandler.loanConfirmHandler(loanConfirmReq, customer);
            result.getSuccess(res);
            logger.debug("贷款成功返回贷款信息endTime{}", result.getEndTime());
            //判断是否发送短信
            try {
                if (StringUtils.isNotBlank(res.getLoanId())) {
                    AmLoanMainInfo amLoanMainInfo = extAmLoanMainInfoMapper.selectByLoanIdAndTenantId(res.getLoanId(), loanConfirmReq.getTenantId());
                    if (null != amLoanMainInfo) {
                        if (StringUtils.isNotBlank(loanConfirmReq.getMerchantName())) {
                            amLoanMainInfo.setMerchantName(loanConfirmReq.getMerchantName());
                            extAmLoanMainInfoMapper.updateByLoanId(amLoanMainInfo);
                        }
                        // 兴安花才需要消费完立即发送信息通知用户，信用就医是隔天发送在另外的job中处理
                        if (Constants.DEFAULT_PRODTCT_CODE.equalsIgnoreCase(loanConfirmReq.getProductId())) {
                            PrProductTable pro = productTableService.findProByProIdAndOrgId(amLoanMainInfo.getProductId(), amLoanMainInfo.getOrganizationId(), amLoanMainInfo.getTenantId());
                            logger.info("是否是下单即放款：" + pro.getRemitWhenLoan());
                            if (TransBizConstant.NO_FLAG.equals(pro.getRemitWhenLoan())) {
                                //判断是否有优惠抵扣
                                BigDecimal trialAmount = loanConfirmReq.getTrialAmount();
                                if (BigDecimal.ZERO.compareTo(trialAmount) < 0) {
                                    logger.info("优惠金额抵扣：{}", trialAmount);
                                    smsService.sendSmsMq(amLoanMainInfo, trialAmount, TransBizConstant.SMS_TYPE_LOAN_DISCOUNT);
                                } else {
                                    smsService.sendSmsMq(amLoanMainInfo, TransBizConstant.SMS_TYPE_LOAN);
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                logger.warn("短信通知异常：{}，直接返回贷款结果",e);
            }
            return result;
        } catch (InterruptedException e) {
            String msg = String.format(TransErrMsgConstant.GET_REDIS_LOCK_ERROR, lockKey);
            logger.error("异常信息{}", e);
            throw new TxnRuntimeException(msg);
        } finally {
            lock.unlock();
        }
    }

    @ApiOperation(value = "贷款试算", notes = "贷款试算API")
    @PostMapping(value = "/loanTrail")
    public TxnRespResult<LoanConfirmRes> loanTrail(@Valid @RequestBody LoanReq loanReq) throws Exception {
        TxnRespResult<LoanConfirmRes> result = new TxnRespResult<>();
        logger.debug("贷款试算开始startTime:{}", result.getStartTime());
        result.getSuccess(loanHandler.loanTrailHandle(loanReq));
        logger.debug("贷款试算结束 返回贷款信息(订单和还款计划)endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "test", notes = "test")
    @PostMapping(value = "/test")
    public TxnRespResult<LoanConfirmRes> test(@Valid @RequestBody TlDisbursementLog log) throws Exception {
        TxnRespResult<LoanConfirmRes> result = new TxnRespResult<>();
        //TlPaymentLog tlPaymentLog = extTlPaymentLogMapper.selectPaymentStatusByPaymentSeqNo(log.getSeqNo(), log.getCustomerId(), "101");
        //iSmsService.paymentProcess(tlPaymentLog);
        TlDisbursementLog tlDisbursementLog = extTlDisbursementLogMapper.selectDisbursementByCondition(log.getLoanId(),  log.getCustomerId(), "101");

        dealGatewayService.buildInnerDisbursementReq(tlDisbursementLog);
        result.getSuccess(null);
        return result;
    }

    @ApiOperation(value = "贷款明细查询", notes = "贷款明细查询API")
    @PostMapping(value = "/loanDetailQuery")
    public TxnRespResult<LoanDetailQueryRes> loanDetailQuery(@Valid @RequestBody LoanQueryReq loanQueryReq)
            throws TxnException {
        TxnRespResult<LoanDetailQueryRes> result = new TxnRespResult<>();
        logger.debug("贷款明细查询开始startTime:{}", result.getStartTime());
        result.getSuccess(loanHandler.loanDetailHandle(loanQueryReq));
        logger.debug("贷款明细查询结束 返回贷款明细查询响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "贷款罚息逾期天数查询", notes = "贷款罚息逾期天数查询查询API")
    @PostMapping(value = "/loanDlayIntcDelqDaysQuery")
    public TxnRespResult<LoanDlayIntcDelqDaysQueryRes> loanDlayIntcDelqDaysQuery(@Valid @RequestBody LoanDlayIntcDelqDaysQueryReq loanDlayIntcDelqDaysQueryReq)
        {
        TxnRespResult<LoanDlayIntcDelqDaysQueryRes> result = new TxnRespResult<>();
        logger.debug("贷款罚息逾期天数查询开始startTime:{}", result.getStartTime());
        result.getSuccess(loanHandler.loanDlayIntcDelqDaysHandle(loanDlayIntcDelqDaysQueryReq));
        logger.debug("贷款罚息逾期天数查询结束 返回贷款罚息逾期天数查询响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "贷款记录查询", notes = "贷款记录查询API")
    @PostMapping(value = "/loanRecordQuery")
    public TxnRespResult<LoanRecordQueryRes> loanRecordQuery(@Valid @RequestBody CommonReq commonReq)
            throws TxnException {
        TxnRespResult<LoanRecordQueryRes> result = new TxnRespResult<>();
        logger.debug("贷款记录查询开始startTime:{}", result.getStartTime());
        result.getSuccess(loanHandler.loanRecordHandle(commonReq));
        logger.debug("贷款记录查询结束 返回贷款记录查询响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "放款状态查询", notes = "放款状态查询API")
    @PostMapping(value = "/disbursementStatusQuery")
    public TxnRespResult<DisbursementStatusQueryRes>
    disbursementStatusQuery(@Valid @RequestBody LoanQueryReq loanQueryReq) throws TxnBizException {
        TxnRespResult<DisbursementStatusQueryRes> result = new TxnRespResult<>();
        logger.debug("放款状态查询开始startTime:{}", result.getStartTime());
        result.getSuccess(loanHandler.disbursementStatusHandle(loanQueryReq));
        logger.debug("放款状态查询结束 返回放款状态查询响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "还款计划查询", notes = "还款计划查询API")
    @PostMapping(value = "/loanPlanQuery")
    public TxnRespResult<LoanPlanQueryRes> loanPlanQuery(@Valid @RequestBody LoanPlanQueryReq loanPlanQueryReq)
            throws TxnException {
        TxnRespResult<LoanPlanQueryRes> result = new TxnRespResult<>();
        logger.debug("还款计划查询开始startTime:{}", result.getStartTime());
        result.getSuccess(loanHandler.loanPlanHandle(loanPlanQueryReq));
        logger.debug("还款计划查询结束 返回还款计划查询响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "订单强制入催", notes = "订单强制入催API")
    @PostMapping(value = "/loanCollection")
    public TxnRespResult<LoanCollectionRes> loanCollection(@Valid @RequestBody LoanCollectionReq loanCollectionReq)
            throws TxnBizException {
        TxnRespResult<LoanCollectionRes> result = new TxnRespResult<>();
        logger.debug("订单强制入催开始startTime:{}", result.getStartTime());
        result.getSuccess(loanHandler.loanCollectionHandle(loanCollectionReq));
        logger.debug("订单强制入催结束endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "当期账单查询", notes = "当期账单查询API")
    @PostMapping(value = "/loanBillQuery")
    public TxnRespResult<LoanBillQueryRes> loanBillQuery(@Valid @RequestBody CommonAddReq commonReq) throws TxnException {
        TxnRespResult<LoanBillQueryRes> result = new TxnRespResult<>();
        logger.debug("当期账单查询开始startTime:{}", result.getStartTime());
        commonReq.checkBizType();
        result.getSuccess(loanHandler.loanBillQueryHandle(commonReq));
        logger.debug("当期账单查询结束 返回查询响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "客户账单查询", notes = "客户账单查询API")
    @PostMapping(value = "/allBillQuery")
    public TxnRespResult<AllBillQueryRes> allBillQuery(@Valid @RequestBody AllBillQueryRep allBillQueryRep)
            throws TxnException {
        TxnRespResult<AllBillQueryRes> result = new TxnRespResult<>();
        logger.debug("客户账单查询开始startTime:{}", result.getStartTime());
        result.getSuccess(loanHandler.allBillQueryHandle(allBillQueryRep));
        logger.debug("客户账单查询结束 返回查询响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "待还账单查询", notes = "待还账单查询API")
    @PostMapping(value = "/allRemainBillQuery")
    public TxnRespResult<AllRemainBillQueryRes> allRemainBillQuery(@Valid @RequestBody CommonAddReq queryReq)
            throws TxnException {
        queryReq.checkBizType();
        TxnRespResult<AllRemainBillQueryRes> result = new TxnRespResult<>();
        logger.debug("待还账单查询开始startTime:{}", result.getStartTime());
        result.getSuccess(loanHandler.allRemainBillQueryHandle(queryReq));
        logger.debug("待还账单查询结束 返回查询响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "账单明细查询", notes = "账单明细查询API")
    @PostMapping(value = "/billDetailQuery")
    public TxnRespResult<BillDetailQueryRes> billDetailQuery(@Valid @RequestBody BillDetailQueryRep billDetailQueryRep)
            throws TxnException {
        TxnRespResult<BillDetailQueryRes> result = new TxnRespResult<>();
        logger.debug("账单明细查询开始 开始时间startTime:{}", result.getStartTime());
        result.getSuccess(loanHandler.billDetailQueryRepHandle(billDetailQueryRep));
        logger.debug("账单明细查询结束 返回贷款记录查询响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "账单分期订单明细查询", notes = "账单分期订单明细查询API")
    @PostMapping(value = "/stagingLoanDetailQuery")
    public TxnRespResult<StagingLoanDetailQueryRes> stagingLoanDetailQuery(
            @Valid @RequestBody StagingLoanDetailQueryRep stagingLoanDetailQueryRep) throws TxnException {
        TxnRespResult<StagingLoanDetailQueryRes> result = new TxnRespResult<>();
        logger.debug("账单分期订单明细查询 开始时间startTime:{}", result.getStartTime());
        result.getSuccess(loanHandler.stagingLoanDetailQueryRepHandle(stagingLoanDetailQueryRep));
        logger.debug("账单分期订单明细查询 返回查询响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "取消订单", notes = "取消订单API")
    @PostMapping(value = "/cancelOrder")
    public TxnRespResult<CancelOrderQueryRes> cancelOrder (@Valid @RequestBody CancelOrderRep cancelOrderRep) throws Exception {
        TxnRespResult<CancelOrderQueryRes> result = new TxnRespResult<>();
        logger.debug("取消订单 开始时间startTime:{}", result.getStartTime());
        CancelOrderQueryRes res = loanHandler.cancelOrderHandle(cancelOrderRep);
        result.getSuccess(res);
        //判断是否发送短信
        if(TransBizConstant.GATEWAY_DEAL_SUC.equals(res.getSunStatus()) && res.getSendSms()){
            AmLoanMainInfo amLoanMainInfo = extAmLoanMainInfoMapper.selectByLoanIdAndTenantId(cancelOrderRep.getLoanId(),cancelOrderRep.getTenantId());
            if(null != amLoanMainInfo){
                //如果不生成流水判断是否需要发送短信
                smsService.sendSmsMq(amLoanMainInfo,TransBizConstant.SMS_TYPE_CANCEL_ORDER);
            }
        }


        logger.debug("取消订单 返回查询响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "放款信息修改", notes = "放款信息修改API")
    @PostMapping(value = "/modifyLoanInfo")
    public TxnRespResult<ModifyLoanInfoRes> modifyLoanInfo(@Valid @RequestBody ModifyLoanInfoReq modifyLoanInfoReq)
            throws Exception {
        TxnRespResult<ModifyLoanInfoRes> result = new TxnRespResult<>();
        logger.debug("放款信息修改 开始时间startTime:{}", result.getStartTime());
        CustomerRes customer = customerService.getCustomerByChannelAndUserId(modifyLoanInfoReq.getChannel(),
                modifyLoanInfoReq.getUserId(), modifyLoanInfoReq.getTenantId());
        String lockKey = String.format(CustomerConstant.LOAN_REDIS_LOCK, modifyLoanInfoReq.getTenantId(),
                customer.getFirstLevel().getCustomerId());
        logger.info("RedissionLock key:{}", lockKey);
        RLock lock = redissonLockService.getRLock(lockKey, LockType.REENTRANT_LOCK);
        try {
            boolean lockFlag = lock.tryLock(CustomerConstant.LOAN_REDIS_LOCK_WAITE_TIME,
                    CustomerConstant.LOAN_REDIS_LOCK_LESS_TIME, TimeUnit.SECONDS);
            logger.info("获取RedissionLock key:{},lockFlag:{}", lockKey, lockFlag);
            if (!lockFlag) {
                logger.error(TxnRespCode.TRANSACTION_PROCESSING.getMsg());
                throw new TxnBizException(TxnRespCode.TRANSACTION_PROCESSING.getCode(),
                        TxnRespCode.TRANSACTION_PROCESSING.getMsg());
            }
            result.getSuccess(loanHandler.modifyLoanInfoHandle(modifyLoanInfoReq));
            return result;
        } catch (InterruptedException e) {
            String msg = String.format(TransErrMsgConstant.GET_REDIS_LOCK_ERROR, lockKey);
            logger.error("异常信息{}", e);
            throw new TxnRuntimeException(msg);
        } finally {
            lock.unlock();
        }
    }

    @ApiOperation(value = "同步API放款失败信息", notes = "同步API放款失败信息")
    @PostMapping(value = "/syncLoanFailInfo")
    public TxnRespResult<CommonRes> syncLoanFailInfoHandle(@Valid @RequestBody SyncLoanFailInfoReq syncLoanFailInfoReq)
            throws TxnException {
        TxnRespResult<CommonRes> result = new TxnRespResult<>();
        logger.debug("同步API放款失败信息 开始时间startTime:{}", result.getStartTime());
        result.getSuccess(loanHandler.syncLoanFailInfoHandle(syncLoanFailInfoReq));
        logger.debug("同步API放款失败信息 返回响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "账单详情查询", notes = "账单详情查询")
    @PostMapping(value = "/billDeailsInquir")
    public TxnRespResult<BillDetailsInquiryRes> billDeailsInquir(@Valid @RequestBody BillDetailsInquiryReq billDetailsInquiryReq) throws Exception {
        TxnRespResult<BillDetailsInquiryRes> result = new TxnRespResult<>();
        logger.debug("账单详情查询开始 开始时间startTime:{}", result.getStartTime());
        billDetailsInquiryReq.checkBizType();
        BillDetailsInquiryRes billDetailsInquiryRes = loanHandler.billDetailsInquir(billDetailsInquiryReq);
        /*if (!Objects.isNull(billDetailsInquiryRes)) {
            List<BillDetail> billDetailList = billDetailsInquiryRes.getBillDetailList();
            if (CollectionUtils.isNotEmpty(billDetailList)) {
                billDetailList.stream().forEach(item -> {
                    if (!DateUtils.sameDate(DateUtils.parseDate(item.getTxnTime()).getTime(), DateUtils.parseDate(item.getCreateTime()).getTime())) {
                        // 23.30 切日后，前端显示实际发生的时间
                        item.setTxnTime(DateUtils.addDay(item.getTxnTime(), -1));
                    }
                });
            }
        }*/
        result.getSuccess(billDetailsInquiryRes);
        logger.debug("账单详情查询结束 返回账单详情查询响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "账单待还明细", notes = "账单待还明细")
    @PostMapping(value = "/billWaitingDetails")
    public TxnRespResult<BillDetailsInquiryRes> billWaitingDetails(@Valid @RequestBody BillDetailsInquiryReq billDetailsInquiryReq) throws Exception {
        TxnRespResult<BillDetailsInquiryRes> result = new TxnRespResult<>();
        logger.debug("账单待还明细开始 开始时间startTime:{}", result.getStartTime());
        billDetailsInquiryReq.checkBizType();
        BillDetailsInquiryRes billDetailsInquiryRes = loanHandler.billWaitingDetails(billDetailsInquiryReq);
        result.getSuccess(billDetailsInquiryRes);
        logger.debug("账单待还明细结束 响应实体endTime{}", result.getEndTime());
        return result;
    }

    @ApiOperation(value = "客户续期信息查询", notes = "客户续期信息查询")
    @PostMapping(value = "/customerRenewalInfo")
    public TxnRespResult<CustomerRenewalRes> customerRenewalInfo(@Valid @RequestBody CommonAddReq req) throws Exception {
        TxnRespResult<CustomerRenewalRes> result = new TxnRespResult<>();
        req.checkBizType();
        CustomerRenewalRes res = iRepaymentPlanService.customerRenewalInfo(req);
        result.getSuccess(res);
        return result;
    }

    @ApiOperation(value = "借款记录查询", notes = "借款记录查询")
    @PostMapping(value = "/loanListQuery")
    public TxnRespResult<LoanListQueryRes> loanListQuery(@Valid @RequestBody LoanListQueryReq req) throws Exception {
        TxnRespResult<LoanListQueryRes> result = new TxnRespResult<>();
        req.checkBizType();
        LoanListQueryRes res = loanHandler.loanListQuery(req);
        result.getSuccess(res);
        return result;
    }

    @ApiOperation(value = "放款结果回调", notes = "放款结果回调API")
    @PostMapping(value = "/callBack")
    public TxnRespResult<LoanCallBackRes> loanCallBack (@Valid @RequestBody LoanCallBackRep req) throws Exception {
        TxnRespResult<LoanCallBackRes> result = new TxnRespResult<>();
        logger.debug("放款结果回调 开始时间startTime:{}", result.getStartTime());
        LoanCallBackRes res = loanHandler.loanCallBackHandle(req);
        result.getSuccess(res);
        logger.debug("放款结果回调 返回查询响应实体endTime{}", result.getEndTime());
        return result;
    }


    @ApiOperation(value = "借款记录查询", notes = "借款记录查询")
    @PostMapping(value = "/queryLoanRecord")
    public TxnRespResult<Boolean> queryLoanRecord(@Valid @RequestBody LoanListQueryReq req) throws Exception {
        TxnRespResult<Boolean> result = new TxnRespResult<>();
        req.checkBizType();
        boolean loanRecordFlag;
        if (Arrays.asList(BizTypeEnum.BIZ_TYPE_XAH.getCode(), BizTypeEnum.BIZ_TYPE_XYJY.getCode()).contains(req.getBizType())) {
            req.setBizType(BizTypeEnum.BIZ_TYPE_XAH.getCode());
            LoanListQueryRes xahRes = loanHandler.loanListQuery(req);
            req.setBizType(BizTypeEnum.BIZ_TYPE_XYJY.getCode());
            LoanListQueryRes xyjyRes = loanHandler.loanListQuery(req);
            loanRecordFlag = CollectionUtils.isNotEmpty(xahRes.getLoanHistories()) || CollectionUtils.isNotEmpty(xyjyRes.getLoanHistories());
        } else {
            LoanListQueryRes res = loanHandler.loanListQuery(req);
            loanRecordFlag = CollectionUtils.isNotEmpty(res.getLoanHistories());
        }
        result.getSuccess(loanRecordFlag);
        return result;
    }

    @ApiOperation(value = "查询总欠款", notes = "查询总欠款")
    @GetMapping(value = "/getLoanTotalAmount")
    public TxnRespResult<BigDecimal> getLoanTotalAmount(@RequestParam String channel,@RequestParam String tenantId,@RequestParam String productId, @RequestParam String customerId) {
        TxnRespResult<BigDecimal> result = new TxnRespResult();
        try {
            result = result.getSuccess(loanHandler.getLoanTotalAmount(channel, customerId, tenantId,productId));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result = result.getFail(TxnRespCode.BIZ_ERROR.getCode(), TxnRespCode.BIZ_ERROR.getUserTips());
        }
        return result;
    }
}
